;
; Copyright (c) Microsoft Corporation.  All rights reserved.
;
;
; Use of this sample source code is subject to the terms of the Microsoft
; license agreement under which you licensed this sample source code. If
; you did not accept the terms of the license agreement, you are not
; authorized to use this sample source code. For the terms of the license,
; please see the license agreement between you and Microsoft or, if applicable,
; see the LICENSE.RTF on your install media or the root of your tools installation.
; THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
;
;
; (C) Copyright 2006 Marvell International Ltd.
; All Rights Reserved
;
; Copyright (c) 1998, 1999 ARM Limited
; All Rights Reserved
;

    OPT     2       ; disable listing
    INCLUDE kxarm.h
    OPT     1       ; reenable listing
    OPT     128     ; disable listing of macro expansions
    INCLUDE armmacros.s


    TEXTAREA


    LEAF_ENTRY      XScaleFlushDCacheL2
;++
; Routine Description:
;    Clean and invalidate the Data Cache.  A bit of a misnomer really.
;       "Flush" describes only invalidating a line.  We use it to for
;       CACHE_SYNC_DISCARD, which is defined as write-back and invalidate.
;
; Syntax:
;	void XScaleFlushDCacheL2(DWORD dwCacheBlocks,
;                              DWORD dwLineSize,
;                              DWORD dwCacheFlushMemoryBase);
;
; Arguments:
;   dwCacheBlocks - number of cache lines in the data cache
;   dwLineSize - number of bytes in each cache line
;   dwCacheFlushMemoryBase - pointer to uncached/unbuffered memory reserved
;                            for cache flush operations.
;
; Return Value:
;       -- none --
; Uses:
;     r0-r4, stacks them on current stack.
;     corrupts CPSR_flags
;


; 
; * This routine cleans & invalidates the entire monahans dcache by set & way.
; * We start at the last set and work backwards.
; * The main loop has been unrolled to reduce loop overhead.
; * #Sets = 256, #ways = 4 per set.  One complete set per loop.  Uses MVA-agnostic approach.
;   
;   *NOTE: Currently ignores the input parameters!!
;


;--

    stmdb   sp!, {r0-r4}    
    
    mov r0, #0x1F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
    add r1, r0, #0x40000000    ; index for way 1
    add r2, r1, #0x40000000    ; index for way 2
    add r3, r2, #0x40000000    ; index for way 3
1
    mcr p15, 0, r0, c7, c14, 2  ; clean&inv set/way0 of L1 dcache specified in r0
    mcr p15, 0, r1, c7, c14, 2  ; clean&inv set/way1 of L1 dcache specified in r1
    mcr p15, 0, r2, c7, c14, 2  ; clean&inv set/way2 of L1 dcache specified in r2
    mcr p15, 0, r3, c7, c14, 2  ; clean&inv set/way3 of L1 dcache specified in r3
 
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    sub  r1, r1, #0x00000020   ; decrement the shifted set index (way1)
    sub  r2, r2, #0x00000020   ; decrement the shifted set index (way2)
    sub  r3, r3, #0x00000020   ; decrement the shifted set index (way3)
    bpl %BT1                   ; go to next set if not done with all sets

    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4

 IF {TRUE}
    
    mov r0, #0x7F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
1
	mov	r1, r0
5	
	mcr p15, 1, r1, c7, c15, 2  ; clean&inv set/way of L2 dcache specified in r1
    cmp r1, #0xd0000000
    addlo r1, r1, #0x20000000
    blo %BT5 
    
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    bpl %BT1  
    
    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4    

 ENDIF
 
    ldmia   sp!, {r0-r4}   

    RETURN

    LEAF_ENTRY      XScaleFlushDCache
;++
; Routine Description:
;    Clean and invalidate the Data Cache.  A bit of a misnomer really.
;       "Flush" describes only invalidating a line.  We use it to for
;       CACHE_SYNC_DISCARD, which is defined as write-back and invalidate.
;
; Syntax:
;	void XScaleFlushDCache(DWORD dwCacheBlocks,
;                              DWORD dwLineSize,
;                              DWORD dwCacheFlushMemoryBase);
;
; Arguments:
;   dwCacheBlocks - number of cache lines in the data cache
;   dwLineSize - number of bytes in each cache line
;   dwCacheFlushMemoryBase - pointer to uncached/unbuffered memory reserved
;                            for cache flush operations.
;
; Return Value:
;       -- none --
; Uses:
;     r0-r4, stacks them on current stack.
;     corrupts CPSR_flags
;


; 
; * This routine cleans & invalidates the entire monahans dcache by set & way.
; * We start at the last set and work backwards.
; * The main loop has been unrolled to reduce loop overhead.
; * #Sets = 256, #ways = 4 per set.  One complete set per loop.  Uses MVA-agnostic approach.
;   
;   *NOTE: Currently ignores the input parameters!!
;


;--

    stmdb   sp!, {r0-r4}    
    
    mov r0, #0x1F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
    add r1, r0, #0x40000000    ; index for way 1
    add r2, r1, #0x40000000    ; index for way 2
    add r3, r2, #0x40000000    ; index for way 3
1
    mcr p15, 0, r0, c7, c14, 2  ; clean&inv set/way0 of L1 dcache specified in r0
    mcr p15, 0, r1, c7, c14, 2  ; clean&inv set/way1 of L1 dcache specified in r1
    mcr p15, 0, r2, c7, c14, 2  ; clean&inv set/way2 of L1 dcache specified in r2
    mcr p15, 0, r3, c7, c14, 2  ; clean&inv set/way3 of L1 dcache specified in r3
 
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    sub  r1, r1, #0x00000020   ; decrement the shifted set index (way1)
    sub  r2, r2, #0x00000020   ; decrement the shifted set index (way2)
    sub  r3, r3, #0x00000020   ; decrement the shifted set index (way3)
    bpl %BT1                   ; go to next set if not done with all sets

    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4
 
    ldmia   sp!, {r0-r4}   

    RETURN


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  mcr p15, 1, r0, c7, c11, 2  ; clean&inv set/way0 of L1 dcache specified in r0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LEAF_ENTRY	XScaleCleanDCacheL2

    stmdb   sp!, {r0-r4}    
    
    mov r0, #0x1F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
    add r1, r0, #0x40000000    ; index for way 1
    add r2, r1, #0x40000000    ; index for way 2
    add r3, r2, #0x40000000    ; index for way 3
1
    mcr p15, 0, r0, c7, c10, 2  ; clean set/way0 of L1 dcache specified in r0
    mcr p15, 0, r1, c7, c10, 2  ; clean set/way1 of L1 dcache specified in r1
    mcr p15, 0, r2, c7, c10, 2  ; clean set/way2 of L1 dcache specified in r2
    mcr p15, 0, r3, c7, c10, 2  ; clean set/way3 of L1 dcache specified in r3
 
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    sub  r1, r1, #0x00000020   ; decrement the shifted set index (way1)
    sub  r2, r2, #0x00000020   ; decrement the shifted set index (way2)
    sub  r3, r3, #0x00000020   ; decrement the shifted set index (way3)
    bpl %BT1                   ; go to next set if not done with all sets

    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4

 IF {TRUE}

    ; Clean L2 Cache
    
    mov r0, #0x7F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
1
	mov	r1, r0
5	
	mcr p15, 1, r1, c7, c11, 2  ; clean set/way of L2 dcache specified in r1
    cmp r1, #0xd0000000
    addlo r1, r1, #0x20000000
    blo %BT5 
    
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    bpl %BT1  
    
    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4    
 
 ENDIF
 
    ldmia   sp!, {r0-r4}           
    
    RETURN    

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;  mcr p15, 1, r0, c7, c11, 2  ; clean&inv set/way0 of L1 dcache specified in r0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LEAF_ENTRY	XScaleCleanDCache

    stmdb   sp!, {r0-r4}    
    
    mov r0, #0x1F00
    orr r0, r0, #0x00E0        ; put NSets (256)-1 into bits 12:5, way 0
    add r1, r0, #0x40000000    ; index for way 1
    add r2, r1, #0x40000000    ; index for way 2
    add r3, r2, #0x40000000    ; index for way 3
1
    mcr p15, 0, r0, c7, c10, 2  ; clean set/way0 of L1 dcache specified in r0
    mcr p15, 0, r1, c7, c10, 2  ; clean set/way1 of L1 dcache specified in r1
    mcr p15, 0, r2, c7, c10, 2  ; clean set/way2 of L1 dcache specified in r2
    mcr p15, 0, r3, c7, c10, 2  ; clean set/way3 of L1 dcache specified in r3
 
    subs r0, r0, #0x00000020   ; decrement the shifted set index (way0)
    sub  r1, r1, #0x00000020   ; decrement the shifted set index (way1)
    sub  r2, r2, #0x00000020   ; decrement the shifted set index (way2)
    sub  r3, r3, #0x00000020   ; decrement the shifted set index (way3)
    bpl %BT1                   ; go to next set if not done with all sets

    ; set up a data write barrier
    mcr     p15, 0, r0, c7, c10, 4

    ldmia   sp!, {r0-r4}           
    
    RETURN    

    END

